home *** CD-ROM | disk | FTP | other *** search
/ Developer Helper 1: Phil & Dave's Excellent CD / Excellent CD HFS.raw / Moof / Goodies / HyperCard Goodies / HyperCard Dev. ToolKit / Serial & MacinTalk XCMDs / XCMD.HowToUse.doc < prev    next >
Text File  |  1987-07-14  |  7KB  |  179 lines

  1. XCMD and XFCN: The Magic Hooks That Extend HyperTalk
  2.  
  3. (This documentation by Ted Kaehler, 14 July 87, HyperCard 1.0B9 and later)
  4.  
  5. Dan Winkler has created an interface that allows powerful new commands 
  6. to be added to HyperCard "in the field."  When a command in a script 
  7. cannot be found, HyperCard looks for a resource of type XCMD with 
  8. the same name as the unknown command.  Likewise, when a function cannot
  9. be found, HyperCard looks for a resource of type XFCN.  Consider XCMDs
  10. and XFCNs to be extensions of stack scripts.  Whenever a handler (for a 
  11. command or function) is not found in a stack script, HyperCard
  12. immediately looks for a XCMD or XFCN in that stack.  The total 
  13. inheritance order is: Button (or Field), Card, Stack, stack XCMD, Home,
  14. home XCMD, HyperCard.  An XCMD or XFCN is a code resource with no 
  15. header bytes (just like a desk accessory).  You can move them from 
  16. file to file with ResEdit or with any other resource moving tool.
  17.  
  18. The only thing passed into an XCMD or XFCN is a pointer to a XCmdBlock.  
  19. It looks like this:
  20.  
  21.   XCmdPtr = ^XCmdBlock;
  22.   XCmdBlock =
  23.     RECORD
  24.       paramCount:  INTEGER;                  { number of arguments }
  25.       params:      ARRAY[1..32] OF Handle;   { the arguments }
  26.       returnValue: Handle;                   { the result of this XCMD }
  27.       passFlag:    BOOLEAN;                  { pass the message on? }
  28.  
  29.       entryPoint:  ProcPtr;                  { call back to HyperCard }
  30.       request:     INTEGER;                  { what you want }
  31.       result:      INTEGER;                  { the answer it gives }
  32.       inArgs:      ARRAY[1..16] OF LongInt;  { args XCMD sends HyperCard }
  33.       outArgs:     ARRAY[1..16] OF LongInt;  { args HyperCard sends back }
  34.     END;
  35.  
  36. You read the agruments (they are handles to zero terminated strings), 
  37. do whatever the purpose of this XCMD is, and optionally store a 
  38. result into returnValue.  All data values going to and from HyperTalk are zero-terminated ASCII
  39. strings.
  40.  
  41. Resources of type XCMD are commands, and resourcs of type XFCN are 
  42. fuctions that return a value.  If you store a result string into 
  43. returnValue in a command, the user can get it by asking for "the result"
  44. (useful for explaining why there was an error).  In a function, you are
  45. expected to store the answer into returnValue.
  46.  
  47. If passFlag is false (the normal case), this XCMD or XFCN has handled the 
  48. message and the script resumes execution.  If passFlag is true, HyperCard
  49. searches the remaining inheritance chain for another handler or
  50. XCMD with the same name.  This is just like the "pass" control structure
  51. in a script.
  52.  
  53. The file Flash.p is an example XCMD.  It takes one argument which is 
  54. the ASCII characters for a decimal integer.  It checks if the number is
  55. even and inverts the screen that number of times.  It is meant to be used 
  56. as a command and puts an error string into "the result" if the argument is
  57. odd.
  58.  
  59. Peek.p is a function (XFCN) that returns the value of any memory location 
  60. in the machine (purists avert your eyes).
  61.  
  62.  
  63. The second part of the XCmdBlock record has to do with 
  64. calling HyperCard back in the middle of your code to ask a question.
  65. If you wanted manage the call to HyperCard yourself, you would 
  66. fill inArgs with your arguments, put a request code in request,
  67. and JSR to the address in entryPoint.  HyperCard returns the values you
  68. requested in outArgs and a reslut code in result.
  69.   
  70. However, Dan Winkler has packaged the entire range of calls on HyperCard,
  71. so that if you are using Pascal, you can simply call a procedure.  Both 
  72. Peek and Flash use some conversion routines that Dan has kindly
  73. supplied.  The file XCmdGlue.inc has the glue procedures.  Handle is always
  74. a handle to a zero-terminated sting.  If a handle is returned, you are
  75. responsible for freeing it.  <<is this true?>>
  76.  
  77. FUNCTION EvalExpr(expr: Str255): Handle;
  78.   Given a HyperTalk expression in ASCII, return a handle to a zero-terminated
  79.   string with the answer.
  80.  
  81. PROCEDURE SendCardMessage(msg: Str255);
  82.   Send a HyperCard message (command) to the current card.
  83.  
  84. FUNCTION GetGlobal(globName: Str255): Handle;
  85.  
  86. PROCEDURE SetGlobal(globName: Str255; globValue: Handle);
  87.  
  88. FUNCTION GetFieldByName(cardFieldFlag: BOOLEAN; fieldName: Str255): Handle;
  89.  
  90. FUNCTION GetFieldByNum(cardFieldFlag: BOOLEAN; fieldNum: INTEGER): Handle;
  91.  
  92. FUNCTION GetFieldByID(cardFieldFlag: BOOLEAN; fieldID: INTEGER): Handle;
  93.  
  94. PROCEDURE SetFieldByName(cardFieldFlag: BOOLEAN; fieldName: Str255; fieldVal: Handle);
  95.  
  96. PROCEDURE SetFieldByNum(cardFieldFlag: BOOLEAN; fieldNum: INTEGER; fieldVal: Handle);
  97.  
  98. PROCEDURE SetFieldByID(cardFieldFlag: BOOLEAN; fieldID: INTEGER; fieldVal: Handle);
  99.  
  100. PROCEDURE ZeroToPas(zeroStr: Ptr; VAR pasStr: Str255);
  101.   Convert a zero terminated string to a Pascal string.  You create the
  102.   Pascal string and pass it in as a VAR parameter.  Useful for converting
  103.   the arguments of any XCMD to Pascal strings.  (See PasToZero below).
  104.  
  105. FUNCTION  StrToNum(str: Str19): LongInt;
  106.   Convert ASCII of a decimal number to the number.
  107.  
  108. FUNCTION  StrToLong(str: Str19): LongInt;
  109.   Convert ASCII of a decimal number to the number.  Negative numbers not
  110.   accepted.
  111.  
  112. FUNCTION StrToExt(str: Str31): Extended;
  113.  
  114.  
  115. FUNCTION StrToBool(str: Str31): BOOLEAN;
  116.   Convert ASCII "true" and "false" to Pascal booleans.
  117.  
  118. FUNCTION StringLength(strPtr: Ptr): LongInt;
  119.  
  120. FUNCTION StringEqual(str1,str2: Str255): BOOLEAN;
  121.  
  122. FUNCTION StringMatch(pattern: Str255; target: Ptr): Ptr;
  123.  
  124. PROCEDURE ReturnToPas(zeroStr: Ptr; VAR pasStr: Str255);
  125.  
  126. PROCEDURE ScanToReturn(VAR scanPtr: Ptr);
  127.  
  128. PROCEDURE ScanToZero(VAR scanPtr: Ptr);
  129.  
  130. PROCEDURE ZeroBytes(dstPtr: Ptr; longCount: LongInt);
  131.  
  132. PROCEDURE CopyBytes(srcPtr,dstPtr: Ptr; byteCount: LongInt);
  133.   Generally useful for moving data in memory.
  134.   
  135. PROCEDURE DivMod(numerator: LongInt; denominator: INTEGER;
  136.                  VAR quotient: LongInt; VAR remainder: INTEGER);
  137.   Division with remainder.
  138.  
  139. FUNCTION  LongToStr(posNum: LongInt): Str19;
  140.   Convert a longInt to decimal ASCII.
  141.  
  142. FUNCTION  NumToStr(num: LongInt): Str19;
  143.   Convert a longInt to decimal ASCII, using a minus sign for negative
  144.   numbers.
  145.  
  146. FUNCTION  NumToHex(num: LongInt; nDigits: INTEGER): Str19;
  147.   Convert a longInt to hexadecimal ASCII, using a minus sign for 
  148.   negative numbers.
  149.  
  150. FUNCTION ExtToStr(num: Extended): Str31;
  151.  
  152. FUNCTION BoolToStr(bool: BOOLEAN): Str31;
  153.   Convert a boolean to ASCII "true" or "false".
  154.   
  155. FUNCTION  PasToZero(str: Str255): Handle;
  156.   Convert a pascal string to a zero-terminated string.  You'll need to do
  157.   this for any result or argument you return to HyperTalk.
  158.  
  159.  
  160. Here are the files you will need:
  161.  
  162.  HyperXCmd.p
  163.  XCmdGlue.inc
  164.  Flash.p  (Example to see how everything is really done.  A command.)
  165.  Peek.p   (Example to see how everything is really done.  A function.)
  166.  
  167. Here are the typical MPW commands for compiling an XCMD
  168.  
  169.     pascal -w SendSerial.p
  170.     link -m ENTRYPOINT -o HyperCommands -rt XCMD=222 -sn Main=SendSerial ∂
  171.       SendSerial.p.o "{MPW}"Libraries:interface.o
  172.  
  173. If you don't use any of the routines in interface.o, its just
  174.  
  175.     pascal Flash.p
  176.     link -o HyperCommands -rt XCMD=0 -sn Main=Flash Flash.p.o
  177.  
  178. After executing these, use ResEdit to move the XCMD or XFCN from 
  179. HyperCommands to the proper stack.